package com.jacob.androidframe.base;

import java.util.ArrayList;
import java.util.List;

import android.support.v7.widget.RecyclerView;
import android.support.v7.widget.RecyclerView.LayoutManager;
import android.view.View;
import android.view.ViewGroup;

public abstract class AdapterRecyclerViewBase<I, VH extends AdapterRecyclerViewBase.ViewHolder> extends android.support.v7.widget.RecyclerView.Adapter<VH>
{
	private List<I> mItemList;

	public AdapterRecyclerViewBase(List<I> pItemList)
	{
		setItemList(pItemList);
	}

    /**
     * 返回数据集中所有Item元素的个数。
     *
     * @return The total number of items in this adapter.
     */
	@Override
	public int getItemCount()
	{
		return mItemList.size();
	}

	/**
	 * <p>返回<code>pPosition</code>位置上的Item类型，以便RecyclerView可以重用ItemView。</p>
	 * <p>本方法默认返回0，即默认假定Adapter中只有1种ItemView类型。 和ListView使用的Adapter不同的是，本方法返回的int值可以是不连续的。</p>
	 * <p>因此，建议使用ItemView对应的XML布局文件的ID作为该类型的返回值。</p>
	 * 
	 * @param pPosition
	 *            position to query
	 * @return integer value identifying the type of the view needed to represent the item at <code>pPosition</code>. Type codes need not be contiguous.
	 */
	@Override
	public int getItemViewType(int pPosition)
	{
		return super.getItemViewType(pPosition);
	}

	/**
	 * <p>返回<code>pPosition</code>位置上的ItemID。</p>
	 * <p>如果 {@link #hasStableIds()} 方法返回false，本方法应该返回 {@link #NO_ID}。</p>
	 * <p>默认返回 {@link #NO_ID}。</p>
	 * 
	 * @param pPosition
	 *            Adapter position to query
	 * @return the stable ID of the item at position
	 */
	@Override
	public long getItemId(int pPosition)
	{
		return super.getItemId(pPosition);
	}

	/**
	 * <p>当RecyclerView需要 {@link ViewHolder} 对象时，调用本方法。</p>
	 * <p>这个ViewHolder对象应该使用对应类型的ItemView对象进行构造。既可以用代码创建ItemView对象，也可以用XML布局文件生成。</p>
	 * <p>这个ViewHolder对象会被当做参数传给 {@link #onBindViewHolder(ViewHolder, int)} 方法，然后用其来显示Item。</p>
	 * <p>因为它会被重用来显示相同类型的Item，所以应该在其内部持有子View的引用，以避免重复调用 {@link View#findViewById(int)} 方法。</p>
	 * 
	 * @param pParent
	 *            生成的ItemView和Item的位置绑定后，会附加到这个ViewGroup
	 * @param pViewType
	 *            生成的ItemView对应的类型
	 * @return ViewHolder对象，其内部持有给定类型的ItemView
	 * @see #getItemViewType(int)
	 * @see #onBindViewHolder(ViewHolder, int)
	 */
	@Override
	public abstract VH onCreateViewHolder(ViewGroup pParent, int pViewType);

	/**
	 * <p>RecyclerView要显示某个位置的Item时调用这个方法。</p>
	 * <p>本方法应该使用给定位置的Item对象，来更新 {@link ViewHolder#itemView} 的内容。</p>
	 * <p>注意：和 {@link android.widget.ListView} 不一样的是，如果mItemList中给定位置的元素没有发生改变的话，RecyclerView是不会再次调用本方法的， 除非Item对象本身是无效的，或者位置无法被确定。</p>
	 * <p>因此，只能在本方法内部使用<code>pPosition</code>参数查询Item对象，并且不可以在外部使用。</p>
	 * <p>如果你需要得到某个Item的位置，应该使用 {@link ViewHolder#getPosition()} 方法返回的最新的位置。</p>
	 * 
	 * @param pHolder
	 *            The ViewHolder which should be updated to represent the contents of the
	 *            item at the given position in the data set.
	 * @param pPosition
	 *            The position of the item within the adapter's data set.
	 */
	@Override
	public abstract void onBindViewHolder(VH pHolder, int pPosition);
	
    /**
     * <p>当Adapter创建的ItemView被回收重用时，调用本方法。</p>
     * <p>当 {@link LayoutManager} 决定某个ItemView不再需要被附加到 {@link RecyclerView} 中时，该ItemView就会被回收。
     * 而ItemView被回收的原因，可能是其被滑出了屏幕，或者其缓存子View仍然被附加在RecyclerView上。
     * 如果ItemView绑定了大量的数据（比如较大的Bitmap），应该在本方法中释放那些资源。</p>
     * 
     * @param pHolder 被回收的ItemView对应的ViewHolder
     */
	@Override
	public void onViewRecycled(VH pHolder)
	{
	}
	
    /**
     * <p>当Adapter创建的ItemView被附加到窗口上时，调用本方法。</p>
     * <p>本方法可以当做ItemView马上就要被用户看到的一个信号。
     * 如果Adapter在 {@link #onViewDetachedFromWindow(RecyclerView.ViewHolder) onViewDetachedFromWindow} 方法中释放了资源，
     * 那么那些资源应该在这里恢复。</p>
     *
     * @param pHolder Holder of the view being attached
     */
	@Override
	public void onViewAttachedToWindow(VH pHolder)
	{
	}
	
    /**
     * <p>当Adapter创建的ItemView从其附加的窗口上分离时，调用本方法。</p>
     * <p>ItemView被从窗口分离出去并不是一定会发生的，Adapter的使用者会根据情况，决定ItemView不可见时是应该缓存，还是从窗口分离。</p>
     *
     * @param pHolder Holder of the view being detached
     */
	@Override
	public void onViewDetachedFromWindow(VH pHolder)
	{
	}

	public void setItemList(List<I> pItemList)
	{
		if (pItemList == null) {
			mItemList = new ArrayList<>();
		} else {
			mItemList = new ArrayList<>(pItemList);
		}
	}

	public static abstract class ViewHolder extends android.support.v7.widget.RecyclerView.ViewHolder
	{
		public ViewHolder(View pItemView)
		{
			super(pItemView);
		}
	}

}
